package com.bytenerd.jianmu.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.bytenerd.jianmu.exception.BusinessException;
import com.bytenerd.jianmu.exception.ErrorCode;
import com.bytenerd.jianmu.model.dto.UserQueryDTO;
import com.bytenerd.jianmu.model.enums.RoleEnum;
import com.bytenerd.jianmu.model.vo.LoginUserVO;
import com.bytenerd.jianmu.model.vo.UserVO;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.bytenerd.jianmu.model.entity.User;
import com.bytenerd.jianmu.mapper.UserMapper;
import com.bytenerd.jianmu.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.bytenerd.jianmu.constant.UserConstant.USER_LOGIN_STATUS;

/**
 * 用户表 服务层实现。
 *
 * @author 程序员bytenerd
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements UserService{

    @Override
    public long register(String account, String password, String checkPassword) {
        // 1. 校验参数
        if(StrUtil.hasBlank(account, password, checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(password.length()<8||checkPassword.length()<8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度不能小于8位");
        }
        if(account.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号长度不能小于4位");
        }
        if(!password.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次输入的密码不一致");
        }
        // 2. 查询用户是否已经存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(User::getAccount,account);
        long count = this.mapper.selectCountByQuery(queryWrapper);
        if(count >0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号已存在");
        }
        // 3. 对密码进行加密
        String encryptPassword = getEncryptPassword(password);
        // 4. 插入数据
        User user = new User();
        user.setAccount(account);
        user.setPassword(encryptPassword);
        user.setUserName("幕友"+this.count());
        user.setRole(RoleEnum.USER.getValue());
        boolean saveResult = this.save(user);
        if(!saveResult){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"注册失败,数据库错误");
        }
        return user.getId();
    }

    @Override
    public LoginUserVO login(String account, String password, HttpServletRequest request) {
        // 1.校验参数
        if(StrUtil.hasBlank(account,password)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(account.length()<4||password.length()<8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号或密码错误");
        }
        // 2.加密
        String encryptPassword = getEncryptPassword(password);
        // 3.查询用户是否存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(User::getAccount,account);
        queryWrapper.eq(User::getPassword,encryptPassword);
        User user = this.mapper.selectOneByQuery(queryWrapper);
        if(user == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户不存在或密码错误");
        }
        // 4.记录用户登入态
        request.getSession().setAttribute(USER_LOGIN_STATUS,user);
        LoginUserVO loginUserVO = getLoginUserVO(user);
        return loginUserVO;
    }

    @Override
    public boolean logout(HttpServletRequest request) {
        User user = (User)request.getSession().getAttribute(USER_LOGIN_STATUS);
        if(user == null || user.getId() == null){
            throw new  BusinessException(ErrorCode.OPERATION_ERROR,"用户未登录");
        }
        request.getSession().removeAttribute(USER_LOGIN_STATUS);
        return true;
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        User user = (User)request.getSession().getAttribute(USER_LOGIN_STATUS);
        if(user == null || user.getId() == null){
            throw new  BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // 从数据库获取最新用户信息
        user = this.getById(user.getId());
        if(user == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return user;
    }


    @Override
    public LoginUserVO getLoginUserVO(User user) {
        if(user ==null){
            return null;
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user,loginUserVO);
        return loginUserVO;
    }

    @Override
    public List<UserVO> getUserVOList(List<User> userList) {
        if(CollUtil.isEmpty(userList)){
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    @Override
    public UserVO getUserVO(User user) {
        if(user==null){
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);
        return userVO;
    }

    @Override
    public QueryWrapper getQueryWrapper(UserQueryDTO userQueryDTO) {
        if(userQueryDTO == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请求参数为空");
        }
        Long id = userQueryDTO.getId();
        String userName = userQueryDTO.getUserName();
        String account = userQueryDTO.getAccount();
        String profile = userQueryDTO.getProfile();
        String role = userQueryDTO.getRole();
        String sortFiled = userQueryDTO.getSortFiled();
        String sortOrder = userQueryDTO.getSortOrder();
        return QueryWrapper.create()
                .eq(User::getId,id)
                .eq(User::getRole,role)
                .like(User::getAccount,account)
                .like(User::getUserName,userName)
                .like(User::getProfile,profile)
                .orderBy(sortFiled,"ascend".equals(sortOrder));
    }

    /**
     * 获取加密后的密码
     * @param password 密码
     * @return;
     */
    @Override
    public String getEncryptPassword(String password){
        String SALT = "bytenerd";
        return DigestUtil.md5Hex(password + SALT);
    }
}
